﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BVCommon.Entities;
using BVClient.ProductServiceReference;
using System.ComponentModel;
using System.Collections.ObjectModel;
using BVClient.OrderServiceReference;

namespace BVClient.Managers
{
    public class OrderProvider
    {
        private IList<Order> orders;
        private ObservableCollection<BVOrder> bvOrders = new ObservableCollection<BVOrder>();
        private bool isLoaded = false;

        public ObservableCollection<BVOrder> GetOrders()
        {
            if (!isLoaded)
            {
                loadData();
            }
            return bvOrders;
        }

        public OrderProvider()
        { }

        private void loadData()
        {
            using (OrderServiceClient client = new OrderServiceClient())
            {
                orders = client.GetData().ToList();
            }
            foreach (Order item in orders)
            {
                bvOrders.Add(new BVOrder(item));
            }
            isLoaded = true;
        }

        public void SaveData()
        {
            using (OrderServiceClient client = new OrderServiceClient())
            {
                IList<Order> list = new List<Order>();
                foreach (BVOrder item in bvOrders)
                {
                    list.Add(ConvertToDbObject(item));
                }
                client.SaveData(list.ToArray());
            }
            orders.Clear();
            bvOrders.Clear();
            loadData();
        }

        private Order ConvertToDbObject(BVOrder sourceItem)
        {
            IEnumerable<Order> dbOrders = (from p in orders
                                               where p.id == sourceItem.Id
                                               select p);
            if (dbOrders.Count() == 0)
            {
                return new Order()
                {
                    order_name = sourceItem.OrderName,
                    order_date = sourceItem.OrderDate
                    //,                    Customer = sourceItem.CustomerName
                };
            }
            else if (dbOrders.Count() == 1)
            {
                dbOrders.ElementAt(0).order_name = sourceItem.OrderName;
                dbOrders.ElementAt(0).order_date = sourceItem.OrderDate;

                return dbOrders.ElementAt(0);
            }
            else
            {
                throw new ArgumentException("Two or more items have equal isentifier");
            }
        }
    }

    public class BVOrder : IDataErrorInfo
    {
        //private readonly Regex nameEx = new Regex(@"^[A-Za-z ]+$");

        public Int32 Id
        { get; set; }

        public string OrderName
        { get; set; }

        public DateTime OrderDate
        { get; set; }

        public string CustomerName
        { get; set; }

        public BVOrder() { }

        public BVOrder(Order order)
        {
            Id = order.id;
            UpdateItem(order);
        }

        public void UpdateItem(Order order)
        {
            OrderName = order.order_name;
            OrderDate = (order.order_date ?? DateTime.Now);
            //CustomerName = order.Customer.name;
        }

        #region IDataErrorInfo Members

        public string Error
        {
            get
            {
                StringBuilder error = new StringBuilder();
                // iterate over all of the properties
                // of this object - aggregating any validation errors
                PropertyDescriptorCollection props = TypeDescriptor.GetProperties(this);
                foreach (PropertyDescriptor prop in props)
                {
                    string propertyError = this[prop.Name];
                    if (propertyError != string.Empty)
                    {
                        error.Append((error.Length != 0 ? ", " : "") + propertyError);
                    }
                }
                return error.ToString();
            }
        }

        public string this[string columnName]
        {
            get
            {
                // apply property level validation rules
                if (columnName.Equals("Name") && String.IsNullOrEmpty(OrderName))
                {
                    return "Order name cannot be null or empty";
                }
                return String.Empty;
            }
        }

        #endregion
    }
}
